import { useEffect, useCallback, useRef } from "react";
import type { PropsWithChildren, CSSProperties } from "react";
import useWatermark from "./useWatermark";

export interface WatermarkProps extends PropsWithChildren {
  /**
   * 自定义样式
   */
  style?: CSSProperties;

  /**
   * 自定义类名
   */
  className?: string;

  /**
   * 水印层级
   */
  zIndex?: number;

  /**
   * 水印宽度
   */
  width?: number;

  /**
   * 水印高度
   */
  height?: number;

  /**
   * 水印旋转角度
   */
  rotate?: number;

  /**
   * 图片水印的资源地址
   */
  image?: string;

  /**
   * 文本水印内容
   */
  content?: string | string[];

  /**
   * 文本水印样式
   */
  fontStyle?: {
    color?: string;
    fontFamily?: string;
    fontSize?: number | string;
    fontWeight?: number | string;
  };

  /**
   * 水印间距 [x轴间距, y轴间距]
   */
  gap?: [number, number];

  /**
   * 水印偏移量 [x轴偏移, y轴偏移]
   */
  offset?: [number, number];

  /**
   * 获取水印容器的函数
   */
  getContainer?: () => HTMLElement | null;
}

/**
 * 水印组件，用于在页面或容器中添加水印
 * @param props WatermarkProps - 水印组件的属性
 * @param props.style 自定义样式
 * @param props.className 自定义类名
 * @param props.zIndex 水印层级
 * @param props.width 水印宽度
 * @param props.height 水印高度
 * @param props.rotate 水印旋转角度
 * @param props.image 图片水印的资源地址
 * @param props.content 文本水印内容
 * @param props.fontStyle 文本水印样式
 * @param props.gap 水印间距 [x轴间距, y轴间距]
 * @param props.offset 水印偏移量 [x轴偏移, y轴偏移]
 * @param props.getContainer 获取水印容器的函数
 * @returns React元素
 */
const Watermark = (props: WatermarkProps) => {
  const {
    className,
    style,
    zIndex,
    width,
    height,
    rotate,
    image,
    content,
    fontStyle,
    gap,
    offset,
  } = props;

  // 创建用于引用容器DOM元素的ref
  const containerRef = useRef<HTMLDivElement>(null);

  // 获取水印容器的回调函数，根据props.getContainer是否存在来决定使用自定义容器或默认容器
  const getContainer = useCallback(() => {
    return props.getContainer ? props.getContainer() : containerRef.current;
  }, [containerRef.current, props.getContainer]);

  // 使用useWatermark hook获取生成水印的方法
  const { generateWatermark } = useWatermark({
    zIndex,
    width,
    height,
    rotate,
    image,
    content,
    fontStyle,
    gap,
    offset,
    getContainer,
  });

  // 当依赖项变化时，重新生成水印
  useEffect(() => {
    generateWatermark({
      zIndex,
      width,
      height,
      rotate,
      image,
      content,
      fontStyle,
      gap,
      offset,
      getContainer,
    });
  }, [
    zIndex,
    width,
    height,
    rotate,
    image,
    content,
    JSON.stringify(props.fontStyle),
    JSON.stringify(props.gap),
    JSON.stringify(props.offset),
    getContainer,
  ]);

  // 如果存在子元素则渲染水印容器
  return props.children ? (
    <div className={className} style={style} ref={containerRef}>
      {props.children}
    </div>
  ) : null;
};

export default Watermark;
